-- MailM
-- Create by chendh
-- 邮件模块

module("MailM", package.seeall);

MAIL_TYPE_SYSTEM            = 1       -- 系统邮件（系统发给指定玩家）
MAIL_TYPE_BOARD             = 2       -- 系统公告（系统发给全服玩家）
MAIL_TYPE_USER              = 3       -- 玩家邮件（玩家发给玩家）
MAIL_TYPE_SYSTEM_RESIDENT   = 4       -- 常驻的系统邮件（系统发给指定玩家，玩家阅读后仍然存在）
MAIL_TYPE_BOARD_RESIDENT    = 5       -- 常驻的系统公告（系统发给全服玩家，玩家阅读后仍然存在）
MAIL_TYPE_USER_RESIDENT     = 6       -- 常驻的玩家邮件（玩家发给玩家，玩家阅读后仍然存在）

MAIL_STATUS_NEW             = 0
MAIL_STATUS_VIEW            = 1

MAIL_FROM_DEFAULT           = "mail_from_default"

local SYSTEM_MAIL_FLAG      = "system_mail_flag"      -- 系统公告邮件状态标记属性名

-- 所有邮件数据，保存客户端收到的所有类型的邮件数据
local allMailsData          = {};
-- 所有邮件显示列表
local allMailsList          = {};
-- 邮件模板
local mailTemplate          = {};

-- 载入配置表
local _init = false;
local loadCsv = function()
    if _init then return end
    _init = true;

    -- 转换下audio信息表
    local mailTemplate_CSV = get_mail_template_CSV();
    for i = 1, #mailTemplate_CSV do
        mailTemplate[mailTemplate_CSV[i].id] = mailTemplate_CSV[i];
    end

    mailTemplate_CSV = {};
end

-- 模块初始化
function init()
    allMailsData = {};
    allMailsList = {};

    loadCsv();
end

-- 收到系统邮件数据
function receiveSystemMails(mails)
    local gameBoardMail = false;
    for _, mailInfo in ipairs(mails) do
        repeat
            -- 有语言版本限制的，则过滤一下
            if type(mailInfo["show_language"]) == "string" and
                mailInfo["show_language"] ~= "*" then
                local list = string.explode(mailInfo["show_language"],"|");
                if table.indexOf(list, getLang()) <= 0 then
                    break;
                end
            end

            local property = mailInfo.property;
            mailInfo.property = property;
            allMailsData[mailInfo.mail_id] = mailInfo;

            if mailInfo["goto"] and mailInfo["goto"] == 1 then
                -- 提示有新公告的邮件
                gameBoardMail = true;
            end
        until true
    end

    if gameBoardMail then
        -- 尝试去拉取WEB公告
        GameBoardM.WebcheckGameBoard();
    end

    -- 抛出邮件数据刷新事件
    EventMgr.fire(event.RECEIVE_MAILS);
end

-- 收到玩家邮件数据
function receiveUserMails(mails)
    for _, mailInfo in ipairs(mails) do
        local property = mailInfo.property;
        mailInfo.property = property;
        allMailsData[mailInfo.mail_rid] = mailInfo;
    end

    -- 抛出邮件数据刷新事件
    EventMgr.fire(event.RECEIVE_MAILS);
end

-- 生成新的邮件显示列表（allMailsList）
function refreshAllMailsList()
    -- 先清空
    allMailsList      = {};

    -- 取出所有邮件信息放到一个table中，用于根据时间排序
    local mailsList     = table.values(allMailsData);

    local function sortMail(a, b)
        local aStatus = checkMailStatus(a);
        local bStatus = checkMailStatus(b);
        if aStatus < bStatus then
            return true;
        elseif aStatus == bStatus then
            return a.send_time > b.send_time;
        else
            return false;
        end
    end

    table.sort(mailsList, sortMail);

    -- 必须在有效期内，是常驻性邮件或者未阅读
    for _, mailInfo in ipairs(mailsList) do
        if isAlive(mailInfo) then
            if isResident(mailInfo) or checkMailStatus(mailInfo) == MAIL_STATUS_NEW then
                if isSystemBoard(mailInfo) then
                    table.insert(allMailsList, mailInfo.mail_id);
                else
                    table.insert(allMailsList, mailInfo.mail_rid);
                end
            end
        end
    end
end

-- 判断是否是系统公告邮件
function isSystemBoard(mailInfo)
    local mailType = mailInfo;

    if type(mailInfo) == "table" then
        mailType = mailInfo.type;
    end

    if mailType == MAIL_TYPE_BOARD or mailType == MAIL_TYPE_BOARD_RESIDENT then
        return true;
    else
        return false;
    end
end

-- 判断是否是系统公告邮件
function isSystemMail(mailInfo)
    local mailType = mailInfo;

    if type(mailInfo) == "table" then
        mailType = mailInfo.type;
    end

    if mailType == MAIL_TYPE_SYSTEM or mailType == MAIL_TYPE_SYSTEM_RESIDENT then
        return true;
    else
        return false;
    end
end

-- 获取邮件显示列表
function getAllMailsList()
    -- 生成新的邮件显示列表（allMailsList）
    refreshAllMailsList();

    return allMailsList;
end

-- 获取邮件信息
function getMailInfo(mailKey)
    return allMailsData[mailKey];
end

-- 获取所有邮件数据
function getAllMailsData()
    return allMailsData;
end

-- 检测邮件状态
function checkMailStatus(mailInfo)
    if isSystemBoard(mailInfo) then
        return checkSystemMailStatus(mailInfo);
    else
        return mailInfo.status or -1;
    end
end

-- 检测系统邮件状态
function checkSystemMailStatus(mailInfo)
    local mailId = mailInfo.mail_id;
    local list = ME.user.dbase:query(SYSTEM_MAIL_FLAG, {});

    if table.indexOf(list, mailId) > 0 then
        return MAIL_STATUS_VIEW;
    else
        return MAIL_STATUS_NEW;
    end
end

-- 标记已阅读
function markView(mailInfo)
    if not isAlive(mailInfo) then
        -- 邮件已过期
        return;
    end

    if isSystemBoard(mailInfo) then
        -- 系统邮件

        -- 必须状态为NEW才能去标记已阅读状态
        if checkMailStatus(mailInfo) == MAIL_STATUS_NEW then
            Operation.cmd_view_system_mail(mailInfo.mail_id);
        end
    else
        -- 非系统邮件，待补充

        -- 必须状态为NEW才能去标记已阅读状态
        if checkMailStatus(mailInfo) == MAIL_STATUS_NEW then
            Operation.cmd_view_user_mail(mailInfo.mail_rid);
        end
    end
end

-- 设置系统邮件已读
function setSystemMailViewed(marilId)
    local mailInfo = getMailInfo(marilId);

    if checkProperty(mailInfo) then
        -- 抛出邮件奖励领取事件
        EventMgr.fire(event.FETCH_MAIL_BONUS);
    end

    -- 抛出邮件数据刷新事件
    EventMgr.fire(event.UPGRADE_MAILS);
end

-- 设置邮件已读
function setUserMailViewed(mailRid)
    local mailInfo = getMailInfo(mailRid);

    mailInfo["status"] = MAIL_STATUS_VIEW;

    if checkProperty(mailInfo) then
        -- 抛出邮件奖励领取事件
        EventMgr.fire(event.FETCH_MAIL_BONUS);
    end

    -- 抛出邮件数据刷新事件
    EventMgr.fire(event.UPGRADE_MAILS);
end

-- 判断邮件是否在有效期
function isAlive(mailInfo)
    local serverTime = TimeM.getServerTime();

    return serverTime < mailInfo.deadline;
end

-- 判断是否是常驻邮件
function isResident(mailInfo)
    return mailInfo.type == MAIL_TYPE_SYSTEM_RESIDENT or mailInfo.type == MAIL_TYPE_BOARD_RESIDENT or mailInfo.type == MAIL_TYPE_USER_RESIDENT;
end

-- 获取未读邮件数据
function getNewMailNum()
    local newMailNum = 0;
    for _, mailInfo in pairs(allMailsData) do
        if isAlive(mailInfo) and checkMailStatus(mailInfo) == MAIL_STATUS_NEW then
            newMailNum = newMailNum + 1;
        end
    end

    return newMailNum;
end

-- 获取邮件图标路径
function getMailIcon(mailInfo)
    if checkProperty(mailInfo) then
        return "icon2";
    else
        return "icon";
    end
end

-- 判断是否是带奖励的邮件
function checkProperty(mailInfo)
    return type(mailInfo.property) == "table" and #mailInfo.property > 0;
end

-- 获取邮件的标题
function getMailName(mailInfo)
    if type(mailInfo.template_id) == "number" and mailInfo.template_id > 0 then
        local templateId = mailInfo.template_id;
        return mailTemplate[templateId].name;
    else
        -- 根据语言版本取标题
        local title = mailInfo["name_" ..  getLang()];
        if not title then
            -- 默认取英文的
            title = mailInfo["name_en"];
        end
        return title;
    end
end

-- 获取邮件的内容
function getMailMessage(mailInfo)
    if type(mailInfo.template_id) == "number" and mailInfo.template_id > 0 then
        local templateId = mailInfo.template_id;
        local message = mailTemplate[templateId].message;

        if templateId == 9 then
            -- 24小时前维护公告邮件，处理下维护日期
            local timeStr = getTimeRangeStr(mailInfo.start_time, mailInfo.end_time);
            message = string.format(message, timeStr);
        elseif templateId == 10 then
            -- 5分钟前维护公告邮件，处理下维护日期
            local function getTimeDesc(t)
                t = t - TimeM.getTimeOffsetDifference();
                local hour = os.date("%H", t);
                local min = os.date("%M", t);
                return hour..":"..min;
            end
            message = string.format(message, getTimeDesc(mailInfo.start_time));
        end

        return message;
    else
        -- 根据语言版本获取内容
        local message = mailInfo["message_" .. getLang()];
        if not message then
            -- 默认取英文的
            message = mailInfo["message_en"];
        end
        return message;
    end
end